/**
 * Create by mzq
 * Description: 封装蓝牙方法
 * Date: 2025/2/13 16:59
 * Update: 2025/2/13 16:59
 */
import store from '@/store'

//设置设备最大传输字节
export function setMTu(deviceId) {
  uni.setBLEMTU({
    deviceId,
    mtu: 157,
    success(res) {
      console.log('set MTU success: ', res)
    },
  })
}

// 写入蓝牙指令操作
export function writeBLECharacteristicValue(value) {
  uni.writeBLECharacteristicValue({
    deviceId: store.state.deviceId,
    serviceId: store.state.serviceId,
    characteristicId: store.state.characteristicId,
    value: value,
    success: (res) => {
      console.log('writeBLECharacteristicValue success', res)
    },
    fail(res) {
      console.log('writeBLECharacteristicValue fail', res)
    },
  })
}

/**
 * 写入蓝牙状态
 * @param type
 * @returns {Promise<unknown>}
 */
export function writeBLEState(type) {
  console.log('当前的type状态是', type)
  return new Promise((resolve, reject) => {
    if (!store.state.isConnected) return resolve(false)
    if (type === 1) {
      // 深度检测
      let buffer = new ArrayBuffer(9)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x09)
      dataView.setUint8(3, 0x01)
      dataView.setUint8(4, 0x00)
      dataView.setUint8(5, 0x00)
      dataView.setUint8(6, 0xd5)
      dataView.setUint8(7, 0x4b)
      dataView.setUint8(8, 0x16)
      writeBLECharacteristicValue(buffer)
    } else if (type === 2) {
      // 快速检测左脑
      let buffer = new ArrayBuffer(9)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x09)
      dataView.setUint8(3, 0x02)
      dataView.setUint8(4, 0x00)
      dataView.setUint8(5, 0x00)
      dataView.setUint8(6, 0x8c)
      dataView.setUint8(7, 0x1b)
      dataView.setUint8(8, 0x16)
      writeBLECharacteristicValue(buffer)
    } else if (type === 3) {
      // 快速检测右脑
      let buffer = new ArrayBuffer(9)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x09)
      dataView.setUint8(3, 0x03)
      dataView.setUint8(4, 0x00)
      dataView.setUint8(5, 0x00)
      dataView.setUint8(6, 0xbb)
      dataView.setUint8(7, 0x2b)
      dataView.setUint8(8, 0x16)
      writeBLECharacteristicValue(buffer)
    } else if (type === 3) {

    } // 专门用于查询佩戴的(也是用深度检测) 5秒发一次
    else if (type === 4) {
      let buffer = new ArrayBuffer(9)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x09)
      dataView.setUint8(3, 0x01)
      dataView.setUint8(4, 0x01)
      dataView.setUint8(5, 0x01)
      dataView.setUint8(6, 0xF6)
      dataView.setUint8(7, 0x5B)
      dataView.setUint8(8, 0x16)
      writeBLECharacteristicValue(buffer)
    } else if (type === 5) { //测试深度
      let buffer = new ArrayBuffer(9)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x09)
      dataView.setUint8(3, 0x01)
      dataView.setUint8(4, 0x05)
      dataView.setUint8(5, 0x05)
      dataView.setUint8(6, 0x7A)
      dataView.setUint8(7, 0x1b)
      dataView.setUint8(8, 0x16)
      writeBLECharacteristicValue(buffer)
    }else if (type === 6) { //单左脑
      let buffer = new ArrayBuffer(9)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x09)
      dataView.setUint8(3, 0x04)
      dataView.setUint8(4, 0x00)
      dataView.setUint8(5, 0x00)
      dataView.setUint8(6, 0x3E)
      dataView.setUint8(7, 0xBB)
      dataView.setUint8(8, 0x16)
      writeBLECharacteristicValue(buffer)
    }else if (type === 7) { //单右脑
      let buffer = new ArrayBuffer(9)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x09)
      dataView.setUint8(3, 0x05)
      dataView.setUint8(4, 0x00)
      dataView.setUint8(5, 0x00)
      dataView.setUint8(6, 0x09)
      dataView.setUint8(7, 0x8B)
      dataView.setUint8(8, 0x16)
      writeBLECharacteristicValue(buffer)
    }else if (type === 10) {
      // 电量
      let buffer = new ArrayBuffer(7)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x08)
      dataView.setUint8(3, 0x10)
      dataView.setUint8(4, 0x57)
      dataView.setUint8(5, 0x04)
      dataView.setUint8(6, 0x16)
      writeBLECharacteristicValue(buffer)
    } else if (type === 12) {
      // 响铃2次
      let buffer = new ArrayBuffer(7)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x08)
      dataView.setUint8(3, 0x12)
      dataView.setUint8(4, 0x77)
      dataView.setUint8(5, 0x46)
      dataView.setUint8(6, 0x16)
      writeBLECharacteristicValue(buffer)
    } else if (type === 13) {
      //   响铃3次
      let buffer = new ArrayBuffer(7)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x08)
      dataView.setUint8(3, 0x13)
      dataView.setUint8(4, 0x67)
      dataView.setUint8(5, 0x67)
      dataView.setUint8(6, 0x16)
      writeBLECharacteristicValue(buffer)
    } else if (type === 15) {
      // 获取芯片ID
      let buffer = new ArrayBuffer(7)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x08)
      dataView.setUint8(3, 0x15)
      dataView.setUint8(4, 0x07)
      dataView.setUint8(5, 0xa1)
      dataView.setUint8(6, 0x16)

      writeBLECharacteristicValue(buffer)
    } else if (type === 16) {
      //获取版本号
      let buffer = new ArrayBuffer(7)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x08)
      dataView.setUint8(3, 0x16)
      dataView.setUint8(4, 0x37)
      dataView.setUint8(5, 0xc2)
      dataView.setUint8(6, 0x16)
      writeBLECharacteristicValue(buffer)
    } else if (type === 17) {
       // 深度检测 断电版本 如果阻抗大于1000就会断电
      //  68 00 09 06 00 00 50 DB 16
       let buffer = new ArrayBuffer(9)
       let dataView = new DataView(buffer)
       dataView.setUint8(0, 0x68)
       dataView.setUint8(1, 0x00)
       dataView.setUint8(2, 0x09)
       dataView.setUint8(3, 0x06)
       dataView.setUint8(4, 0x00)
       dataView.setUint8(5, 0x00)
       dataView.setUint8(6, 0x50)
       dataView.setUint8(7, 0xDB)
       dataView.setUint8(8, 0x16)
       writeBLECharacteristicValue(buffer)
    } else if (type === 40){
      // 关闭06和空闲负载检测的自动关机功能
      let buffer = new ArrayBuffer(7)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x08)
      dataView.setUint8(3, 0x17)
      dataView.setUint8(4, 0x27)
      dataView.setUint8(5, 0xE3)
      dataView.setUint8(6, 0x16)
      writeBLECharacteristicValue(buffer)
    }else if(type === 50){
      // 开启06和空闲负载检测的自动关机功能
      let buffer = new ArrayBuffer(7)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x08)
      dataView.setUint8(3, 0x18)
      dataView.setUint8(4, 0xD6)
      dataView.setUint8(5, 0x0C)
      dataView.setUint8(6, 0x16)
      writeBLECharacteristicValue(buffer)
    } else if (type === 80) {
      //   老版本的获取头环电量
      let buffer = new ArrayBuffer(7)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x07)
      dataView.setUint8(3, 0x0f)
      dataView.setUint8(4, 0xa4)
      dataView.setUint8(5, 0xe4)
      dataView.setUint8(6, 0x16)
      writeBLECharacteristicValue(buffer)
    } else if (type === 99) {
      // 停止/复位
      let buffer = new ArrayBuffer(7)
      let dataView = new DataView(buffer)
      dataView.setUint8(0, 0x68)
      dataView.setUint8(1, 0x00)
      dataView.setUint8(2, 0x08)
      dataView.setUint8(3, 0x99)
      dataView.setUint8(4, 0x57)
      dataView.setUint8(5, 0xa5)
      dataView.setUint8(6, 0x16)
      writeBLECharacteristicValue(buffer)
    }
  })
}

/**
 * ArrayBuffer转16进度字符串示例
 * @param buffer
 * @returns {string}
 */
export function ab2hex(buffer) {
  const hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('')
}

/**
 * 字节转小数
 * @param byteStr
 * @returns {number}
 */

export function convertFloat(byteStr) {
  let arrayBuffer = new Uint8Array(byteStr).buffer
  var dataView = new DataView(arrayBuffer)
  return dataView.getFloat32(0)
}

/**
 * 校验包的完整性并取出
 * @param buffer
 */
export function checkPackage(buffer) {
  for (let i = 0; i < buffer.length; i++) {
    if (buffer[i] === 0x68) {
      let lenBytes = [buffer[i + 1], buffer[i + 2]]
      let packLen = BytesToIntBigEndian(lenBytes)
      if (packLen <= buffer.length) {
        if (buffer[i + packLen - 1] === 0x16) {
          let crcContent = buffer.slice(i + 1, i + packLen - 3)
          let crc16 = crc16_false(crcContent)
          if (
            buffer[i + packLen - 3] === crc16[0] &&
            buffer[i + packLen - 2] === crc16[1]
          ) {
            let totalData = buffer.splice(i, packLen)
            return totalData
          }
        }
      }
    }
  }
}

// crc16算法
export function crc16_false(buffer) {
  var crc = 0xffff
  let polynomial = 0x1021
  for (var index = 0; index < buffer.length; index++) {
    var b = buffer[index]
    for (var i = 0; i < 8; i++) {
      let bit = ((b >> (7 - i)) & 1) == 1
      let c15 = ((crc >> 15) & 1) == 1
      crc <<= 1
      if (c15 ^ bit) crc ^= polynomial
    }
  }
  var hi = (crc & 0xff00) >> 8 //高位置
  var lo = crc & 0x00ff //低位置
  return [hi, lo]
}

/**
 * 字节转number
 * @param bytes
 * @returns {number}
 */
export function BytesToIntBigEndian(bytes) {
  let val = 0
  for (let i = 0; i < bytes.length; ++i) {
    val += bytes[i]
    if (i < bytes.length - 1) {
      val = val << 8
    }
  }
  return val
}
